﻿#region Disclaimer/Info
///////////////////////////////////////////////////////////////////////////////////////////////////
// MetaCollection
// 
// MetaCollection is a system to provide a standard structure, permissions and metadata service
// for content organization.
//
// This project is hosted at Google Code at http://code.google.com/p/metacollection/
//
// This project is licensed under the BSD license.  See the License.txt file for more information.
///////////////////////////////////////////////////////////////////////////////////////////////////
#endregion

using System;
using System.Configuration;
using System.Linq;
using System.Web;
using MetaCollection.ContentService.Configuration;
using MetaCollection.ContentService.Http;
using MetaCollection.Framework;
using System.Security.Principal;
using MetaCollection.Framework.Security;
using MetaCollection.Framework.Model;

namespace MetaCollection.ContentService
{
	/// <summary>
	/// Module for processing HTTP Request in IIS7.  Checks to see if the requested URL
	/// exists as an item within the collection.
	/// </summary>
	[CLSCompliant(false)]
	public class ContentModule : IHttpModule 
	{
		/// <summary>
		/// Which methods are configured as enabled.
		/// </summary>
		private HttpMethods m_SupportedMethods = HttpMethods.None;
		/// <summary>
		/// content request handler
		/// </summary>
		private ContentHandler m_ContentHandler;
		/// <summary>
		/// Content Endpoint
		/// </summary>
		private ContentEndpoint m_ContentEndpoint;
		private IRequestHandler m_Handler;

		/// <summary>
		/// Initializes a new instance of the <see cref="ContentModule"/> class.
		/// </summary>
		public ContentModule()
		{
			ContentConfigurationSection config = (ContentConfigurationSection)ConfigurationManager.GetSection("contentConfiguration");
			m_SupportedMethods = config.Controllers.AllowedMethods;
			m_Handler = RequestHandlerFactory.CreateRequestHandler();
			m_ContentHandler = new ContentHandler(m_Handler);
			m_ContentEndpoint = new ContentEndpoint(m_Handler, m_SupportedMethods);
		}
		 
		/// <summary>
		/// Registers the Content Module with PostResolveRequestCache and PostAuthenticateRequest events
		/// </summary>
		/// <param name="context">the http application to register with</param>
		public void Init(HttpApplication context)
		{
			if (context == null)
				throw new ArgumentNullException("context");

			context.PostResolveRequestCache += new EventHandler(context_PostResolveRequestCache);
			context.PostAuthenticateRequest += new EventHandler(context_PostAuthenticateRequest);
		}

		/// <summary>
		/// Handles the PostResolveRequestCache event of the context control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		void context_PostResolveRequestCache(object sender, EventArgs e)
		{
			HttpContext context = ((HttpApplication)sender).Context;
			if (!m_ContentEndpoint.IsValidPath(context))
				return;

			context.Items.Add("SupportedMethods", m_SupportedMethods);
			context.RemapHandler(m_ContentHandler);
		}

		/// <summary>
		/// Handles the PostAuthenticateRequest event of the HttpApplication.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		void context_PostAuthenticateRequest(object sender, EventArgs e)
		{
			HttpContext context = ((HttpApplication)sender).Context;
			// set context.User to be a MetaPrincipal with roles coming from our role provider
			var roles = from r in System.Web.Security.Roles.GetRolesForUser(context.User.Identity.Name).AsEnumerable<string>()
						select (IItemClaim) new ItemClaim { ClaimType = MetaPrincipal.RoleClaimType, Id = Guid.Empty, ClaimValue = r, Rights = AccessRights.Unknown };
			context.User = new MetaPrincipal(context.User.Identity, roles);
		}


		/// <summary>
		/// Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule"/>.
		/// </summary>
		public void Dispose()
		{
			m_ContentEndpoint.Dispose();
			m_Handler.Dispose();
		}
	}
}
